package com.alibaba.csp.sentinel.demo.zuul.gateway.sentinel;

import com.alibaba.csp.sentinel.adapter.gateway.zuul.api.ZuulGatewayApiMatcherManager;
import com.alibaba.csp.sentinel.adapter.gateway.zuul.api.matcher.RequestContextApiMatcher;
import com.alibaba.csp.sentinel.adapter.gateway.zuul.constants.ZuulConstant;
import com.alibaba.csp.sentinel.adapter.gateway.zuul.fallback.BlockResponse;
import com.alibaba.csp.sentinel.adapter.gateway.zuul.filters.SentinelZuulPreFilter;
import com.alibaba.csp.sentinel.demo.zuul.gateway.vo.BaseResultVo;
import com.alibaba.fastjson.JSON;
import com.netflix.zuul.context.RequestContext;
import lombok.SneakyThrows;

import java.util.*;


/**
 * 自定义网关限流，排除指定url
 * 七、设置routeId和apis接口互斥
 * Apis中有的， 就不要走routeId规则了
 *
 * @author GaoZhiqiang
 * @date 2021-03-26 10:42:15
 */
public class CustomSentinelZuulPreFilter extends SentinelZuulPreFilter {

    public CustomSentinelZuulPreFilter(int i) {
        super(i);
    }

    @SneakyThrows
    @Override
    public Object run() {

    /*    RequestContext ctx = RequestContext.getCurrentContext();
        String routeId = (String) ctx.get(ZuulConstant.PROXY_ID_KEY);

        Set<String> matchingApis = pickMatchingApiDefinitions(ctx);
        if (!matchingApis.isEmpty()) {
            //路由Id重置为null
            ctx.set(ZuulConstant.PROXY_ID_KEY, null);
        }*/


        Object run = super.run();


        RequestContext ctx = RequestContext.getCurrentContext();
        if (ctx.getResponseStatusCode() == 429) {

            //最终抛出来的异常是ZuulException； 走SendErrorFilter#run 接口转发
            throw new RuntimeException("访问频率测试，请勿频繁点击，如有问题联系技术人员！");
/*

            this.setFailedRequest(JSON.toJSONString(BaseResultVo.error("访问过于频繁")), 200);
*/

        }

        return run;
    }

    /**
     * 网关抛异常
     *
     * @param body
     * @param code
     */
    private void setFailedRequest(String body, int code) {
        RequestContext ctx = RequestContext.getCurrentContext();
        ctx.setResponseStatusCode(code);
        ctx.getResponse().setContentType("application/json;charset=UTF-8");
        ctx.setResponseBody(body);
        // 路由转发停止
        ctx.setSendZuulResponse(false);
    }


    private Set<String> pickMatchingApiDefinitions(RequestContext requestContext) {
        Set<String> apis = new HashSet<>();
        Collection<RequestContextApiMatcher> values = ZuulGatewayApiMatcherManager.getApiMatcherMap().values();
        for (RequestContextApiMatcher matcher : values) {
            if (matcher.test(requestContext)) {
                apis.add(matcher.getApiName());
            }
        }
        return apis;
    }

}
